package com.zcx.mall.oauth.controller;

import com.zcx.mall.common.web.api.ApiResult;
import com.zcx.mall.common.web.constants.ErrorCodeConstants;
import com.zcx.mall.common.web.exception.BizExcepton;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.util.StringUtils;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.*;

@RestController
@RequestMapping("/oauth")
@Slf4j
public class OauthController {


    @Autowired
    @Lazy
    private TokenStore tokenStore;

    @Autowired
    private TokenEndpoint tokenEndpoint;


    /**
     * 重写login接口
     *
     * @param principal
     * @param parameters
     * @return
     * @throws HttpRequestMethodNotSupportedException
     */
    @PostMapping("/token")
    public ApiResult<Map<String, Object>> postAccessToken(Principal principal,
                                                       @RequestBody Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        OAuth2AccessToken accessToken;
        ApiResult<Map<String, Object>> result = new ApiResult<>();

        try {
            accessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
            Map<String, Object> resultMap = new LinkedHashMap<>();
            // token信息
            resultMap.put("access_token", accessToken.getValue());
            resultMap.put("token_type", accessToken.getTokenType());
            resultMap.put("expires_in", accessToken.getExpiresIn());
            resultMap.put("scope", StringUtils.arrayToDelimitedString(accessToken.getScope().toArray(), ","));
            resultMap.putAll(accessToken.getAdditionalInformation());
            // 权限信息
            Collection<? extends GrantedAuthority> authorities =
                    tokenStore.readAuthentication(accessToken).getUserAuthentication().getAuthorities();
            List<String> list = new ArrayList<>();
            for (GrantedAuthority authority : authorities) {
                list.add(authority.getAuthority());
            }
            resultMap.put("authorities", list);
            result.setContent(resultMap);
        }
        catch (InvalidGrantException e) {
            log.info("校验用户名密码失败");
            throw new BizExcepton(ErrorCodeConstants.LoginError);
        }

        return result;
    }

}